<?php
namespace CbjCode\TpGeneral\Library\AliYum;

use OSS\Core\OssException;
use OSS\OssClient;

class AliOssUpload
{

    protected $error = '';

    /**
     * 获取签名
     * @param $name
     * @param $md5
     * @param $fileSize
     * @return array|false
     * @throws OssException
     */
    protected function params($name,$md5,$fileSize)
    {
        if (!$this->check()){
            return false;
        }
        $chunk = 0;
        $auth = new \addons\alioss\library\Auth();
        $params = $auth->params($name, $md5);
        $params['OSSAccessKeyId'] = $params['id'];
        $params['success_action_status'] = 200;
        $config = get_addon_config('alioss');
        if ($chunk) {
            $oss = new OssClient($config['accessKeyId'], $config['accessKeySecret'], $config['endpoint']);
            $chunkSize = 4194304;
            $uploadId = $oss->initiateMultipartUpload($config['bucket'], $params['key']);
            $params['uploadId'] = $uploadId;
            $params['parts'] = $oss->generateMultiuploadParts($fileSize, $chunkSize);
            $params['partsAuthorization'] = [];
            $date = gmdate('D, d M Y H:i:s \G\M\T');
            foreach ($params['parts'] as $index => $part) {
                $partNumber = $index + 1;
                $signstr = "PUT\n\n\n{$date}\nx-oss-date:{$date}\n/{$config['bucket']}/{$params['key']}?partNumber={$partNumber}&uploadId={$uploadId}";
                $authorization = base64_encode(hash_hmac('sha1', $signstr, $config['accessKeySecret'], true));
                $params['partsAuthorization'][$index] = $authorization;
            }
            $params['date'] = $date;
        }
        return $params;
    }


    /**
     * 检查签名是否正确或过期
     */
    protected function check()
    {
        $aliosstoken = getAliosstoken();
        if (!$aliosstoken) {
            $this->setError("参数不正确");
            return false;
        }
        $config = get_addon_config('alioss');
        list($accessKeyId, $sign, $data) = explode(':', $aliosstoken);
        if (!$accessKeyId || !$sign || !$data) {
            $this->setError("参数不正确");
            return false;
        }
        if ($accessKeyId !== $config['accessKeyId']) {
            $this->setError("参数不正确");
            return false;
        }
        if ($sign !== base64_encode(hash_hmac('sha1', base64_decode($data), $config['accessKeySecret'], true))) {
            $this->setError("签名不正确");
            return false;
        }
        $json = json_decode(base64_decode($data), true);
        if ($json['deadline'] < time()) {
            $this->setError("请求已经超时");
            return false;
        }
        return true;
    }

    /**
     * @param string $url 图片路径
     * @param string $filePath 图片真实绝对路径
     * @return bool
     * @throws OssException
     */
    public function upload(string $url, string $filePath): bool
    {
        if (config('upload.storage')=='alioss'){
            if (!$this->check()){
                return false;
            }
            $config = get_addon_config('alioss');
            $oss = new OssClient($config['accessKeyId'], $config['accessKeySecret'], $config['endpoint']);
            try {
                $oss->uploadFile($config['bucket'], ltrim($url, "/"), $filePath);
                //成功不做任何操作
            } catch (\Exception $e) {
                @unlink($filePath);
                $this->setError('上传失败');
                return false;
            }
        }
        return true;
    }

    public function getError(): string
    {
        return $this->error;
    }

    public function setError($err = ''){
        $this->error = $err;
    }
}